package com.superman.mvpframe.client.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONException;
import com.google.gwt.json.client.JSONNull;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;

/**
 * JSON工具类
 * 
 * @author superman
 * @version 2016年12月27日下午3:48:24
 */
public class XJsonUtil {
	// 以下是json格式中标准的三个节点对应的key
	private static final String KEY_OF_BODY = "body";
	private static final String KEY_OF_COUNT = "count";
	private static final String KEY_OF_LIST = "list";

	// private static final String KEY_OF_BODY = "BODY";
	// private static final String KEY_OF_LIST = "LIST";
	// private static final String KEY_OF_COUNT = "COUNT";

	protected static JSONArray encodeList(List<Object> data) {
		JSONArray jsona = new JSONArray();
		for (int i = 0; i < data.size(); i++) {
			Object val = data.get(i);
			if (val instanceof Map) {
				jsona.set(i, encodeMap((Map<String, Object>) val));
			} else if (val instanceof List) {
				jsona.set(i, encodeList((List<Object>) val));
			} else if (val instanceof String) {
				jsona.set(i, new JSONString(val.toString()));
			} else if (val instanceof Number) {
				jsona.set(i, new JSONNumber(Double.parseDouble(val.toString())));
			} else if (val instanceof Boolean) {
				jsona.set(i, JSONBoolean.getInstance((Boolean) val));
			} else if (val == null) {
				jsona.set(i, JSONNull.getInstance());
			} else if (val instanceof Date) {
				jsona.set(i, new JSONString(val.toString()));
			}
		}
		return jsona;
	}

	/**
	 * list->jsonarray
	 * 
	 * @author superman
	 * @version 2018年8月28日 上午11:09:07
	 * @param list
	 * @return
	 */
	public static JSONArray encodeStringListToJsonArray(List<String> list) {

		JSONArray jsona = new JSONArray();
		if (list == null || list.size() == 0)
			return jsona;
		else {
			for (int i = 0; i < list.size(); i++) {
				Object val = list.get(i);
				jsona.set(i, new JSONString(val.toString()));
			}
			return jsona;
		}

	}

	protected static JSONObject encodeMap(Map<String, Object> data) {
		JSONObject jsobj = new JSONObject();
		for (String key : data.keySet()) {
			Object val = data.get(key);
			// 去除key中头尾空格
			key = key.trim();
			if (val instanceof String) {
				jsobj.put(key, new JSONString(val.toString()));
			} else if (val instanceof Date) {
				jsobj.put(key, new JSONString(val.toString()));
			} else if (val instanceof Number) {
				jsobj.put(key, new JSONNumber(Double.parseDouble(val.toString())));
			} else if (val instanceof Boolean) {
				jsobj.put(key, JSONBoolean.getInstance((Boolean) val));
			} else if (val == null) {
				jsobj.put(key, JSONNull.getInstance());
			} else if (val instanceof Map) {
				jsobj.put(key, encodeMap((Map<String, Object>) val));
			} else if (val instanceof List) {
				jsobj.put(key, encodeList((List<Object>) val));
			} else if (val instanceof Object[]) {
				Object[] o = (Object[]) val;
				jsobj.put(key, encodeList(Arrays.asList(o)));
			} else if (val instanceof JSONObject) {
				jsobj.put(key, (JSONObject) val);
			} else if (val instanceof JSONArray) {
				jsobj.put(key, (JSONArray) val);
			}
		}

		return jsobj;
	}

	/**
	 * 解析请求的响应中body JSON串为Map对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:48:34
	 * @param str
	 * @return Map<String, Object>
	 */
	public static Map<String, Object> getBody(String str) {
		if (getJOBody(str) != null)
			return getMap(getJOBody(str));
		else
			return null;
	}

	/**
	 * 解析请求响应中的count值
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:49:30
	 * @param str
	 * @return int
	 */
	public static int getCount(String str) {
		JSONObject jo = JSONParser.parseStrict(str).isObject();
		JSONObject body = jo.get(KEY_OF_BODY).isObject();
		return (int) (body.get(KEY_OF_COUNT).isNumber().doubleValue());
	}

	/**
	 * 解析请求的响应中body JSON串为JSONObject对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:49:07
	 * @param str
	 * @return JSONObject
	 */
	public static JSONObject getJOBody(String str) {
		JSONObject jo = JSONParser.parseStrict(str).isObject();
		if (jo.get(KEY_OF_BODY) == null)
			return null;
		else {
			JSONObject body = jo.get(KEY_OF_BODY).isObject();
			return body;
		}
	}

	/**
	 * 将json数组转换成List数组
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:49:47
	 * @param list
	 * @return List<Map<String, Object>>
	 */
	public static List<Map<String, Object>> getList(JSONArray list) {
		List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < list.size(); i++) {
			JSONObject item = list.get(i).isObject();
			maps.add(getMap(item));
		}
		return maps;
	}

	/**
	 * 解析请求响应中的JSON数组为List对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:50:37
	 * @param str
	 * @return List<Map<String, Object>>
	 */
	public static List<Map<String, Object>> getList(String str) {
		return getList(str, KEY_OF_LIST);
	}

	/**
	 * 解析请求响应中的JSON数组为List<Map<String, Object>>对象,可指定key
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:51:26
	 * @param str
	 * @param key
	 * @return List<Map<String, Object>>
	 */
	public static List<Map<String, Object>> getList(String str, String key) {
		JSONObject jo = JSONParser.parseStrict(str).isObject();
		JSONObject body = jo.get(KEY_OF_BODY).isObject();
		if (body.get(key) == null)
			return null;
		else
			return getList(body.get(key).isArray());
	}

	/**
	 * 解析请求响应中的JSON数组
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:51:47
	 * @param str
	 * @return JSONArray
	 */
	public static JSONArray getListJsonArray(String str) {
		JSONObject jo = JSONParser.parseStrict(str).isObject();
		return jo.get(KEY_OF_LIST).isArray();
	}

	/**
	 * 将JSONObject对象转换成Map对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:52:08
	 * @param jo
	 * @return Map<String, Object>
	 */
	public static Map<String, Object> getMap(JSONObject jo) {
		if (jo == null)
			throw new JSONException("传入的JSONObject不能为空");
		else {
			Map<String, Object> map = new LinkedHashMap<String, Object>();
			Iterator<String> it = jo.keySet().iterator();
			while (it.hasNext()) {
				String name = it.next();
				if (jo.get(name) != null) {
					JSONValue val = jo.get(name);
					if (val.isString() != null)
						map.put(name, val.isString().stringValue());
					else if (val.isNumber() != null)
						map.put(name, val.isNumber().doubleValue());
					else if (val.isArray() != null)
						map.put(name, val.isArray());
					else if (val.isObject() != null)
						map.put(name, val.isObject());
					else if (val.isBoolean() != null) {
						map.put(name, val.isBoolean().booleanValue());
					}
				}
			}
			return map;
		}
	}

	/**
	 * 解析JSON数组对象为List<Object>对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:52:35
	 * @param list
	 * @return List<Object>
	 */
	public static List<Object> getOnlyList(JSONArray list) {
		List<Object> objs = new ArrayList<Object>();
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).isString() != null)
				objs.add(list.get(i).isString().stringValue());
			else if (list.get(i).isNumber() != null)
				objs.add(list.get(i).isNumber().doubleValue());
		}
		return objs;
	}

	/**
	 * 解析JSON数组对象为List<String>对象
	 * 
	 * @author superman
	 * @version 2017年9月14日 上午9:41:48
	 * @param list
	 * @return List<String>
	 */
	public static List<String> getStrList(JSONArray list) {
		List<String> objs = new ArrayList<String>();
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).isString() != null)
				objs.add(list.get(i).isString().stringValue());
		}
		return objs;
	}

	/**
	 * 将Json字符串解析成Map格式的对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:53:22
	 * @param jsonStr
	 * @return Map<String, Object>
	 */
	public static Map<String, Object> jsonToObjectMap(String jsonStr) {
		JSONObject jo = JSONParser.parseStrict(jsonStr).isObject();
		return getMap(jo);
	}

	/**
	 * 将List<Map<String, Object>>对象转换成JSON数组
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:53:47
	 * @param list
	 * @return JSONArray
	 */
	public static JSONArray objMapListToJsonArr(List<Map<String, Object>> list) {
		JSONArray ja = new JSONArray();
		for (int i = 0; i < list.size(); i++) {
			ja.set(i, objMapToJsonObj(list.get(i)));
		}
		return ja;
	}

	/**
	 * 将List<Map<String, Object>>对象转换成JSON字符串
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:53:47
	 * @param list
	 * @return String
	 */
	public static String objMapListToJsonStr(List<Map<String, Object>> list) {
		return objMapListToJsonArr(list).toString();
	}

	/**
	 * 将 Map对象转换成JSONObject对象
	 * 
	 * @author superman
	 * @version 2016年12月27日 下午3:54:17
	 * @param map
	 * @return JSONObject
	 */
	public static JSONObject objMapToJsonObj(Map<String, Object> map) {
		if (map == null || map.size() == 0)
			return new JSONObject();
		else
			return encodeMap(map);
	}
}
